package com.yn.pet.controller.app.biz;


import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yn.pet.bus.entity.DeviceInfo;
import com.yn.pet.bus.entity.DeviceSim;
import com.yn.pet.bus.entity.GenFenceAlarm;
import com.yn.pet.bus.enums.DeviceStatusEnum;
import com.yn.pet.controller.pc.request.FenceQueryRequest;
import com.yn.pet.controller.pc.request.FenceSaveRequest;
import com.yn.pet.controller.pc.request.FenceUpdateRequest;
import com.yn.pet.controller.pc.response.FenceQueryResponse;
import com.yn.pet.controller.tcpserver.PetServer808Service;
import com.yn.pet.bus.entity.GenFence;

import com.yn.pet.entity.AppUser;
import com.yn.pet.enums.CircleActionEnum;
import com.yn.pet.bus.enums.FenceTypeEnum;
import com.yn.pet.protocol.t808.T0001;
import com.yn.pet.protocol.t808.T8600;
import com.yn.pet.protocol.t808.T8601;
import com.yn.pet.protocol.t808.T8602;
import com.yn.pet.service.DeviceInfoService;
import com.yn.pet.service.DeviceSimService;
import com.yn.pet.service.GenFenceAlarmService;
import com.yn.pet.service.GenFenceService;
import com.yn.pet.util.AppTokenUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.data.geo.Point;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class  AGenFenceBizService {
private final GenFenceService fenceService;
private final DeviceSimService simService;

private final DeviceInfoService deviceInfoService;

private final PetServer808Service petServer808Service;
private final GenFenceAlarmService fenceAlarmService;

    /**
     * 用户添加围栏信息
     * @param request 请求参数
     *
     */
    @Transactional
    public void saveFence(FenceSaveRequest request) {
        //获取设备信息，如果设备不在线返回错误信息
        LambdaQueryWrapper<DeviceInfo> wrapper1 = Wrappers.lambdaQuery();
        wrapper1.eq(DeviceInfo::getDeviceId, request.getDeviceId());
        DeviceInfo deviceInfo = deviceInfoService.getOne(wrapper1);
        if(deviceInfo == null){
            throw new RuntimeException("设备信息不存在");
        }
        /*if(Objects.equals(deviceInfo.getDeviceStatus(), DeviceStatusEnum.OFFLINE.getCode())){
            throw new RuntimeException("设备已离线,无法立即添加围栏信息");
        }*/

        //获取当前登录用户
        AppUser appUser = AppTokenUtil.getAppUser();
        if(appUser==null){
            throw new RuntimeException("当前用户未登录");
        }
        Long userId = appUser.getAppUserId();
        String fenceName = request.getFenceName();
        fenceName = fenceName.trim();
        //根据围栏名称判断是否已经创建
        LambdaQueryWrapper<GenFence> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(GenFence::getFenceName, fenceName);
        wrapper.eq(GenFence::getDeviceId, request.getDeviceId());
        wrapper.eq(GenFence::getIsDelete, 0);
        if(fenceService.getOne(wrapper)!=null){
            throw new RuntimeException("围栏名称已存在");
        }

        //根据设备id，围栏类型，经纬度，区域范围查询db,判断用户是否已经创建
        LambdaQueryWrapper<GenFence> queryGenFence = new LambdaQueryWrapper<>();
        queryGenFence.eq(GenFence::getDeviceId, request.getDeviceId())
                .eq(GenFence::getFenceType, request.getFenceType())
                .eq(GenFence::getUserId, userId);

        if (Objects.equals(request.getFenceType(), FenceTypeEnum.CIRCLE.getCode())) {
            queryGenFence.eq(GenFence::getCenterLat, request.getCenterLat())
                    .eq(GenFence::getCenterLng, request.getCenterLng())
                    .eq(GenFence::getRadius, request.getRadius());
        } else {
            queryGenFence.eq(GenFence::getVertices, request.getVertices());
        }
        //查逻辑删除为false的
        queryGenFence.eq(GenFence::getIsDelete, 0);
        GenFence one = fenceService.getOne(queryGenFence);
        if (one != null) {
            throw new RuntimeException("围栏已存在");
        }

        //添加围栏
        GenFence transform = FenceSaveRequest.transform(request);
        transform.setUserId(userId);
        transform.setEnableTime(new Date());
        transform.setCreateTime(new Date());
        transform.setUpdateTime(new Date());
        boolean save = fenceService.save(transform);
        if (!save) {
            throw new RuntimeException("添加失败");
        }
        log.info("添加围栏成功：{}", transform);
    }

    /**
     * 用户删除围栏信息
     * @param fenceId 围栏id
     * @return
     */
    @Transactional
    public void removeFence(Long fenceId) {


        //获取当前登录用户
        AppUser appUser = AppTokenUtil.getAppUser();
        if(appUser==null){
            throw new RuntimeException("当前用户未登录");
        }
        Long userId = appUser.getAppUserId();

        //查询db中围栏信息
        GenFence genFence = fenceService.selectFenceById(fenceId);
        if(genFence==null){
            throw new RuntimeException("围栏不存在");
        }
        if(!genFence.getUserId().equals(userId)){
            throw new RuntimeException("当前用户无权限操作此围栏");
        }
        //获取设备信息，如果设备不在线返回错误信息
        LambdaQueryWrapper<DeviceInfo> wrapper1 = Wrappers.lambdaQuery();
        wrapper1.eq(DeviceInfo::getDeviceId, genFence.getDeviceId());
        DeviceInfo deviceInfo = deviceInfoService.getOne(wrapper1);
        if(deviceInfo == null){
            throw new RuntimeException("设备信息不存在");
        }
        if(Objects.equals(deviceInfo.getDeviceStatus(), DeviceStatusEnum.OFFLINE.getCode())){
            throw new RuntimeException("设备已离线,无法删除围栏信息");
        }
        fenceService.deleteById(fenceId);
        //删除围栏警告记录表中的该围栏记录
        LambdaUpdateWrapper<GenFenceAlarm> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(GenFenceAlarm::getFenceId, fenceId);
        fenceAlarmService.remove(wrapper);
    }

    /**
     * 用户批量删除围栏信息
     * @param fenceIdSet 围栏id集合
     * @return
     */
    @Transactional
    public void removeFenceBatch(Set<Long> fenceIdSet) {
        //获取当前登录用户
        AppUser appUser = AppTokenUtil.getAppUser();
        if(appUser==null){
            throw new RuntimeException("当前用户未登录");
        }
        Long userId = appUser.getAppUserId();

        LambdaQueryWrapper<GenFence> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.in(GenFence::getFenceId, fenceIdSet);
        lambdaQuery.eq(GenFence::getIsDelete, 0);//未逻辑删除
        List<GenFence> fenceList = fenceService.list(lambdaQuery);

        if(CollectionUtils.isEmpty(fenceList)){
            throw new RuntimeException("围栏不存在");
        }
        //获取设备信息，如果设备不在线返回错误信息
        LambdaQueryWrapper<DeviceInfo> wrapper1 = Wrappers.lambdaQuery();
        wrapper1.eq(DeviceInfo::getDeviceId, fenceList.get(0).getDeviceId());
        DeviceInfo deviceInfo = deviceInfoService.getOne(wrapper1);
        if(deviceInfo == null){
            throw new RuntimeException("设备信息不存在");
        }
        if(Objects.equals(deviceInfo.getDeviceStatus(), DeviceStatusEnum.OFFLINE.getCode())){
            throw new RuntimeException("设备已离线,无法删除围栏信息");
        }

        ArrayList<Long> fenceIds = new ArrayList<>(fenceList.size());
        fenceList.forEach(fence -> {
            if(!Objects.equals(fence.getUserId(), userId)){
                throw new RuntimeException("当前用户无权限操作围栏信息");
            }
            fenceIds.add(fence.getFenceId());
        });
        fenceService.deleteByIds(fenceIds);

        fenceIds.forEach(fenceId -> {
            //删除围栏警告记录表中的该围栏记录
            LambdaUpdateWrapper<GenFenceAlarm> wrapper = Wrappers.lambdaUpdate();
            wrapper.eq(GenFenceAlarm::getFenceId, fenceId);
            fenceAlarmService.remove(wrapper);
        });
    }

    /**
     * 用户修改围栏信息
     * @param request 修改围栏信息
     * @return
     */
    @Transactional
    public void updateFence(FenceUpdateRequest request) {
        //获取当前登录用户
        AppUser appUser = AppTokenUtil.getAppUser();
        if(appUser==null){
            throw new RuntimeException("当前用户未登录");
        }
        Long userId = appUser.getAppUserId();
        GenFence fence = fenceService.selectFenceById(request.getFenceId());
        if(fence == null) {
            throw new RuntimeException("围栏不存在");
        }
        if(!fence.getUserId().equals(userId)) {
            throw new RuntimeException("当前用户无权限修改该围栏信息");
        }
        //获取设备信息，如果设备不在线返回错误信息
        LambdaQueryWrapper<DeviceInfo> wrapper1 = Wrappers.lambdaQuery();
        wrapper1.eq(DeviceInfo::getDeviceId, fence.getDeviceId());
        DeviceInfo deviceInfo = deviceInfoService.getOne(wrapper1);
        if(deviceInfo == null){
            throw new RuntimeException("设备信息不存在");
        }
        /*if(Objects.equals(deviceInfo.getDeviceStatus(), DeviceStatusEnum.OFFLINE.getCode())){
            throw new RuntimeException("设备已离线,无法修改围栏信息");
        }*/
        //根据围栏名称查询该名称的围栏，如果存在则返回错误信息
        String fenceName = request.getFenceName();
        fenceName = fenceName.trim();
        Long count = fenceService.lambdaQuery()
                .eq(GenFence::getFenceName, fenceName)
                .eq(GenFence::getIsDelete, 0)
                .eq(GenFence::getDeviceId, fence.getDeviceId())
                .ne(GenFence::getFenceId, request.getFenceId())
                .count();
        if(count > 0) {
            throw new RuntimeException("围栏名称已存在");
        }

        //构建更新条件
        LambdaUpdateWrapper<GenFence> lambdaUpdate = Wrappers.lambdaUpdate();
        lambdaUpdate.eq(GenFence::getFenceId, request.getFenceId());
        lambdaUpdate.set(GenFence::getFenceName, request.getFenceName());
        lambdaUpdate.set(GenFence::getFenceAddress, request.getFenceAddress());
        if(Objects.equals(fence.getFenceType(), FenceTypeEnum.CIRCLE.getCode())){
            //圆形
           lambdaUpdate.set(GenFence::getCenterLat, request.getCenterLat());
           lambdaUpdate.set(GenFence::getCenterLng, request.getCenterLng());
           lambdaUpdate.set(GenFence::getRadius, request.getRadius());
        }else{
           lambdaUpdate.set(GenFence::getVertices, request.getVertices());
        }
        fenceService.update(lambdaUpdate);

    }

    /**
     * 用户分页查询围栏信息
     * @param request 分页查询参数
     * @return IPage<FenceQueryResponse>
     */
    public IPage<FenceQueryResponse> pageList(FenceQueryRequest request) {
        int currentPage = 1;
        int pageSize = 10;
        if (request.getCurrentPage() != null) {
            currentPage = request.getCurrentPage();
        }
        if (request.getPageSize() != null) {
            pageSize = request.getPageSize();
        }
        //查询电子围栏信息
        LambdaQueryWrapper<GenFence> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(GenFence::getIsDelete,0);
        lambdaQuery.eq(GenFence::getDeviceId,request.getDeviceId());
        Page<GenFence> page = fenceService.page(new Page<>(currentPage, pageSize), lambdaQuery);
        if(CollectionUtils.isEmpty(page.getRecords())){
            return new Page<>();
        }
        return page.convert(FenceQueryResponse::transform);
    }

    /**
     * 查询围栏详情
     * @param fenceId 围栏ID
     * @return FenceQueryResponse
     */
    public FenceQueryResponse queryById(Long fenceId) {
        LambdaQueryWrapper<GenFence> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(GenFence::getFenceId, fenceId);
        return FenceQueryResponse.transform(fenceService.getOne(lambdaQuery));
    }

    /**
     * 是否启用围栏
     * @param fenceId 围栏ID
     * @param status 状态 0:禁用,1:启用
     * @return
     */
    @Transactional
    public void isUse(Long fenceId, Integer status) {
        //获取登录用户
        AppUser appUser = AppTokenUtil.getAppUser();
        if(appUser == null) {
            throw new RuntimeException("当前用户未登录");
        }
        Long userId = appUser.getAppUserId();
        GenFence fence = fenceService.selectFenceById(fenceId);
        if(fence == null) {
            throw new RuntimeException("围栏不存在");
        }
        if(!fence.getUserId().equals(userId)) {
            throw new RuntimeException("当前用户无权限修改该围栏信息");
        }
        //构建更新条件
        LambdaUpdateWrapper<GenFence> lambdaUpdate = Wrappers.lambdaUpdate();
        lambdaUpdate.eq(GenFence::getFenceId, fenceId);
        lambdaUpdate.set(GenFence::getUseStatus, status);
        fenceService.update(lambdaUpdate);
    }
}
